home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / system-tools / hdenv / hdenv.c < prev    next >
C/C++ Source or Header  |  1996-04-10  |  11KB  |  359 lines

  1. /*****************************************************************************\
  2.  
  3. HDEnv 1.4 (10.4.96)
  4. Copyright (C) 1995/96 by Michael Fedrowitz <mfedrowi@ix.urz.uni-heidelberg.de>
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. \*****************************************************************************/
  21.  
  22.  
  23. #include <exec/types.h>
  24. #include <exec/memory.h>
  25. #include <dos/dos.h>
  26. #include <proto/dos.h>
  27. #include <proto/exec.h>
  28. #include <stdlib.h>
  29. #include <strings.h>
  30. #include <dos.h>
  31.  
  32.  
  33. #ifndef V39
  34. void * __asm AsmCreatePool(register __d0 ULONG,register __d1 ULONG,register __d2 ULONG,register __a6 struct ExecBase *);
  35. void __asm AsmDeletePool(register __a0 void *,register __a6 struct ExecBase *);
  36. void * __asm AsmAllocPooled(register __a0 void *,register __d0 ULONG,register __a6 struct ExecBase *);
  37. void __asm AsmFreePooled(register __a0 void *,register __a1 void *,register __d0 ULONG,register __a6 struct ExecBase *);
  38.  
  39. #define CreatePool(memFlags,puddleSize,threshSize) AsmCreatePool(memFlags,puddleSize,threshSize,SysBase)
  40. #define DeletePool(poolHeader) AsmDeletePool(poolHeader,SysBase)
  41. #define AllocPooled(poolHeader,memSize) AsmAllocPooled(poolHeader,memSize,SysBase)
  42. #define FreePooled(poolHeader,memory,memSize) AsmFreePooled(poolHeader,memory,memSize,SysBase)
  43. #endif
  44.  
  45. #define VERSIONTAG "$VER: HDEnv 1.4 " __AMIGADATE__
  46.  
  47. #define TEMPLATE "IGNORE/K/M,ALL/S,VERBOSE/S,NODEL/S,NOCOPY/S,TEST/S"
  48.  
  49. #define ARG_IGNORE  0
  50. #define ARG_ALL     1
  51. #define ARG_VERBOSE 2
  52. #define ARG_NODEL   3
  53. #define ARG_NOCOPY  4
  54. #define ARG_TEST    5
  55.  
  56. #define ERR_BREAK 10001
  57.  
  58. #define COPYBUF 2048
  59.  
  60.  
  61. struct File {
  62.  
  63.     struct File *next,*prev;
  64.     struct FileInfoBlock fib;
  65.     char path[1];
  66. };
  67.  
  68. struct Dir {
  69.  
  70.     struct File *first,*last;
  71. };
  72.  
  73. struct HDEnv {
  74.  
  75.     void *pool;
  76.     struct Dir env,envarc,ignore;
  77.     char path[256];
  78.     char copybuf[COPYBUF];
  79.     long verbose,test;
  80. };
  81.  
  82.  
  83. #ifdef V39
  84. const long __oslibversion = 39;
  85. #else
  86. const long __oslibversion = 37;
  87. #endif
  88.  
  89. const char *versiontag = VERSIONTAG;
  90.  
  91. struct HDEnv *hde = NULL;
  92.  
  93. long error_code = 0;
  94.  
  95.  
  96. void __regargs _CXBRK(void) {
  97.  
  98.     error_code = ERR_BREAK;
  99. }
  100.  
  101.  
  102. void free_all(void) {
  103.  
  104.     DeletePool(hde->pool);
  105.     FreeMem(hde,sizeof(struct HDEnv));
  106. }
  107.  
  108. struct HDEnv *alloc_all(void) {
  109.  
  110.     struct HDEnv *hde;
  111.  
  112.     if(hde = AllocMem(sizeof(struct HDEnv),MEMF_CLEAR)) {
  113.         if(!(hde->pool = CreatePool(MEMF_CLEAR,10000,10000))) {
  114.             FreeMem(hde,sizeof(struct HDEnv));
  115.             hde = NULL;
  116.         }
  117.     }
  118.     if(!hde) error_code = ERROR_NO_FREE_STORE;
  119.  
  120.     return hde;
  121. }
  122.  
  123.  
  124. void add_file(struct Dir *dir,char *path,struct FileInfoBlock *fib) {
  125.  
  126.     struct File *file;
  127.  
  128.     if(file = AllocPooled(hde->pool,sizeof(struct File)+strlen(path))) {
  129.         if(fib) memcpy(&file->fib,fib,sizeof(struct FileInfoBlock));
  130.         strcpy(file->path,path);
  131.         if(dir->first) {
  132.             dir->last->next = file;
  133.             file->prev = dir->last;
  134.         }
  135.         else dir->first = file;
  136.         dir->last = file;
  137.     }
  138.     else error_code = ERROR_NO_FREE_STORE;
  139. }
  140.  
  141. void scan_dir(struct Dir *dir,char *name) {
  142.  
  143.     BOOL rc;
  144.     BPTR l;
  145.     long err;
  146.     char *path;
  147.     struct FileInfoBlock *fib;
  148.  
  149.     if(fib = AllocDosObject(DOS_FIB,NULL)) {
  150.         if(path = AllocPooled(hde->pool,256)) {
  151.             if(l = Lock(name,ACCESS_READ)) {
  152.                 rc = Examine(l,fib);
  153.                 if(rc) rc = ExNext(l,fib);
  154.                 while(rc) {
  155.                     strmfp(path,name,fib->fib_FileName);
  156.                     add_file(dir,path,fib);
  157.                     if(fib->fib_DirEntryType > 0) scan_dir(dir,path);
  158.                     chkabort();
  159.                     if(error_code) break;
  160.                     rc = ExNext(l,fib);
  161.                 }
  162.                 if(!error_code) {
  163.                     err = IoErr();
  164.                     if(err != ERROR_NO_MORE_ENTRIES) error_code = err;
  165.                 }
  166.                 UnLock(l);
  167.             }
  168.             FreePooled(hde->pool,path,256);
  169.         }
  170.         else error_code = ERROR_NO_FREE_STORE;
  171.         FreeDosObject(DOS_FIB,fib);
  172.     }
  173.     else error_code = ERROR_NO_FREE_STORE;
  174. }
  175.  
  176. struct File *find_file(struct Dir *dir,char *name) {
  177.  
  178.     struct File *file;
  179.  
  180.     file = dir->first;
  181.  
  182.     while(file) {
  183.         if(!(stricmp(file->path,name))) break;
  184.         file = file->next;
  185.     }
  186.  
  187.     return file;
  188. }
  189.  
  190.  
  191. void del_files(void) {
  192.  
  193.     struct File *file;
  194.  
  195.     file = hde->env.last;
  196.  
  197.     while(file) {
  198.         if(!find_file(&hde->ignore,file->path)) {
  199.             if(!(find_file(&hde->envarc,file->path))) {
  200.                 strmfp(hde->path,"ENV:",file->path);
  201.                 if(hde->test) Printf("%s\n",hde->path);
  202.                 else {
  203.                     if(hde->verbose) Printf("deleting %s...\n",hde->path);
  204.                     if(!(DeleteFile(hde->path))) error_code = IoErr();
  205.                 }
  206.             }
  207.         }
  208.         chkabort();
  209.         if(error_code) break;
  210.         file = file->prev;
  211.     }
  212. }
  213.  
  214.  
  215. void copy_files(void) {
  216.  
  217.     struct File *file,*dest;
  218.     BOOL copy;
  219.     BPTR l,src_fh,dest_fh;
  220.     long size,allocsize,bufsize,rc;
  221.     void *buf;
  222.  
  223.     file = hde->envarc.first;
  224.  
  225.     while(file) {
  226.         copy = FALSE;
  227.         if(!find_file(&hde->ignore,file->path)) {
  228.             strmfp(hde->path,"ENV:",file->path);
  229.             if(!(dest = find_file(&hde->env,file->path))) {
  230.                 if(file->fib.fib_DirEntryType > 0) {
  231.                     if(hde->test) Printf("%s (created)\n",hde->path);
  232.                     else {
  233.                         if(hde->verbose) Printf("creating %s...\n",hde->path);
  234.                         if(!(l = CreateDir(hde->path))) {
  235.                             error_code = IoErr();
  236.                             break;
  237.                         }
  238.                         else UnLock(l);
  239.                     }
  240.                 }
  241.                 else copy = TRUE;
  242.             }
  243.             else if(file->fib.fib_DirEntryType < 0) {
  244.                 if(CompareDates(&file->fib.fib_Date,&dest->fib.fib_Date)) copy = TRUE;
  245.             }
  246.         }
  247.  
  248.         if(copy) {
  249.             if(hde->test) Printf("ENVARC:%s to %s\n",file->path,hde->path);
  250.             else {
  251.                 if(hde->verbose) Printf("copying ENVARC:%s to %s...\n",file->path,hde->path);
  252.                 if(src_fh = Open(file->path,MODE_OLDFILE)) {
  253.                     if(dest_fh = Open(hde->path,MODE_NEWFILE)) {
  254.                         buf = NULL;
  255.                         size = file->fib.fib_Size;
  256.                         if(size > COPYBUF) {
  257.                             if(buf = AllocPooled(hde->pool,size)) {
  258.                                 allocsize = size;
  259.                                 bufsize = size;
  260.                             }
  261.                         }
  262.                         if(!buf) {
  263.                             buf = hde->copybuf;
  264.                             bufsize = COPYBUF;
  265.                             allocsize = 0;
  266.                         }
  267.                         while(size > 0) {
  268.                             if(size < bufsize) bufsize = size;
  269.                             rc = Read(src_fh,buf,bufsize);
  270.                             if(rc == bufsize) rc = Write(dest_fh,buf,bufsize);
  271.                             if(rc != bufsize) {
  272.                                 error_code = IoErr();
  273.                                 break;
  274.                             }
  275.                             if(size < bufsize) bufsize = size;
  276.                             size -= bufsize;
  277.                         }
  278.                         if(allocsize) FreePooled(hde->pool,buf,allocsize);
  279.                         Close(dest_fh);
  280.                         if(error_code) DeleteFile(hde->path);
  281.                         else {
  282.                             rc = SetFileDate(hde->path,&file->fib.fib_Date);
  283.                             rc &= SetProtection(hde->path,file->fib.fib_Protection);
  284.                             rc &= SetComment(hde->path,file->fib.fib_Comment);
  285.                         }
  286.                         if(!rc) error_code = IoErr();
  287.                     }
  288.                     else error_code = IoErr();
  289.                     Close(src_fh);
  290.                 }
  291.                 else error_code = IoErr();
  292.             }
  293.         }
  294.         chkabort();
  295.         if(error_code) break;
  296.         file = file->next;
  297.     }
  298. }
  299.  
  300.  
  301. int main(void) {
  302.  
  303.     struct RDArgs *rda;
  304.     char **ignore;
  305.     long arg[6] = { 0,0,0,0,0,0 };
  306.     BPTR env,envarc,old;
  307.     int i;
  308.  
  309.     if(hde = alloc_all()) {
  310.         if(rda = ReadArgs(TEMPLATE,arg,NULL)) {
  311.             hde->verbose = arg[ARG_VERBOSE];
  312.             hde->test = arg[ARG_TEST];
  313.             if(env = Lock("ENV:",ACCESS_READ)) {
  314.                 if(envarc = Lock("ENVARC:",ACCESS_READ)) {
  315.                     old = CurrentDir(env);
  316.                     scan_dir(&hde->env,"");
  317.                     CurrentDir(envarc);
  318.                     scan_dir(&hde->envarc,"");
  319.                     if(!arg[ARG_ALL]) {
  320.                         add_file(&hde->ignore,"Kickstart",NULL);
  321.                         add_file(&hde->ignore,"Workbench",NULL);
  322.                         add_file(&hde->ignore,"Language",NULL);
  323.                     }
  324.                     if(ignore = (char **)arg[ARG_IGNORE]) {
  325.                         i=0;
  326.                         while(ignore[i]) add_file(&hde->ignore,ignore[i++],NULL);
  327.                     }
  328.                     if(!error_code && !arg[ARG_NODEL]) {
  329.                         if(hde->test) Printf("Would have deleted:\n");
  330.                         del_files();
  331.                     }
  332.                     if(!error_code && !arg[ARG_NOCOPY]) {
  333.                         if(hde->test) Printf("Would have copied:\n");
  334.                         copy_files();
  335.                     }
  336.                     CurrentDir(old);
  337.                     UnLock(envarc);
  338.                 }
  339.                 else error_code = IoErr();
  340.                 UnLock(env);
  341.             }
  342.             else error_code = IoErr();
  343.             FreeArgs(rda);
  344.         }
  345.         else error_code = IoErr();
  346.         free_all();
  347.     }
  348.  
  349.     if(error_code) {
  350.         if(error_code != ERR_BREAK) {
  351.             PrintFault(error_code,"HDEnv");
  352.             return RETURN_FAIL;
  353.         }
  354.         else PutStr("*** Break\n");
  355.     }
  356.  
  357.     return RETURN_OK;
  358. }
  359.